package com.zz.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.io.InputStream;
import java.util.*;

/**
 * @Author zhangbin
 * @Create 2022-12-09 16:34
 * @Description 调用 CRM API 接口
 */

@Slf4j
@UtilityClass
public class CrmApiUtil {

    /**
     * 获取 【api_supported = true】 可以访问的所有模块名称
     *
     * @param accessToken token
     * @return 模块数据
     */
    public static List<String> getAllModuleName(String accessToken) {
        List<String> moduleList = new ArrayList<>();

        // 1 所有模块名称
        JSONObject record = HttpUtil.getData("https://www.zohoapis.com.cn/crm/v3/settings/modules"
                , new HashMap<String, String>() {{
                    put("Authorization", "Zoho-oauthtoken " + accessToken);
                }});
        if (Objects.nonNull(record)) {
            JSONArray modules = record.getJSONArray("modules");
            //System.out.println("modules.toJSONString() = " + modules.toJSONString());
            if (Objects.nonNull(modules) && modules.size() > 0) {
                for (int i = 0; i < modules.size(); i++) {
                    JSONObject jsonObject = modules.getJSONObject(i);
                    //String moduleName = jsonObject.getString("module_name");
                    String moduleName = jsonObject.getString("api_name");
                    if (jsonObject.getBoolean("api_supported")
                            && jsonObject.getBoolean("global_search_supported")
                            && jsonObject.getBoolean("visible")
                            && jsonObject.getBoolean("viewable")
                            && jsonObject.getBoolean("show_as_tab")
                    ) {
                        moduleList.add(moduleName);
                    }
                }
            }
        }
        return moduleList;
    }

    /**
     * 返回所有模块数据
     *
     * @param accessToken token
     * @param url         请求地址
     * @param fieldList   要查询的字段，id默认查出
     * @return 模块数据集合
     */
    public static List<JSONObject> getModuleData(String accessToken, String url, List<String> fieldList) {
        Set<JSONObject> set = new HashSet<>();
        boolean flag;
        String pageToken = "";
        StringBuilder str = new StringBuilder(url);
        str.append("?");
        for (int i = 0; i < fieldList.size(); i++) {
            if (i == 0) {
                str.append("fields=");
            }
            str.append(fieldList.get(i));
            if (i != fieldList.size() - 1) {
                str.append(",");
            }
        }
        String baseUrl = str.toString();
        url = baseUrl + "&page=1&per_page=200";
        do {
            try {
                if (StringUtils.isNotBlank(pageToken)) {
                    url = baseUrl + "&per_page=200&page_token=";
                    url += pageToken;
                }
                JSONObject record = HttpUtil.getData(url
                        , new HashMap<String, String>() {{
                            put("Authorization", "Zoho-oauthtoken " + accessToken);
                        }});
                JSONArray data = record.getJSONArray("data");
                set.addAll(data.toJavaList(JSONObject.class));
                flag = record.getJSONObject("info").getBoolean("more_records");
                pageToken = record.getJSONObject("info").getString("next_page_token");
            } catch (Exception e) {
                e.printStackTrace();
                flag = false;
            }
        } while (flag);

        return new ArrayList<>(set);
    }

    /**
     * 根据id查询模块数据
     *
     * @param accessToken token
     * @param url         请求地址
     * @param id          模块id
     * @return 模块数据
     */
    public static JSONObject getDataById(String accessToken, String url, String id) {
        url += "/";
        url += id;

        JSONObject record = HttpUtil.getData(url
                , new HashMap<String, String>() {{
                    put("Authorization", "Zoho-oauthtoken " + accessToken);
                }});
        if (Objects.nonNull(record)) {
            JSONArray data = record.getJSONArray("data");
            if (Objects.nonNull(data)) {
                return data.getJSONObject(0);
            }
        }
        return null;
    }

    /**
     * //* 按照搜索条件，返回模块的所有数据，指定要查询的字段，路径使用【V2】版本
     *
     * @param accessToken token
     * @param url         请求地址
     * @return 模块数据集合
     */
    public static List<JSONObject> getModuleDataBySearch(String accessToken, String url) {
        Set<JSONObject> set = new HashSet<>();
        boolean flag = false;
        int page = 1;
        do {
            try {
                JSONObject record = HttpUtil.getData(url + "&page=" + page + "&per_page=200"
                        , new HashMap<String, String>() {{
                            put("Authorization", "Zoho-oauthtoken " + accessToken);
                        }});
                if (Objects.nonNull(record)) {
                    JSONArray data = record.getJSONArray("data");
                    if (Objects.nonNull(data)) {
                        set.addAll(data.toJavaList(JSONObject.class));
                        flag = record.getJSONObject("info").getBoolean("more_records");
                        page++;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                flag = false;
            }
        } while (flag);
        return new ArrayList<>(set);
    }

    /**
     * 根据 userId 查询user信息
     *
     * @param accessToken token
     * @param userId      用户id
     * @return 用户信息
     */
    public static List<JSONObject> getUserDataById(String accessToken, String userId) {
        String url = "https://www.zohoapis.com.cn/crm/v3/users/";
        url += userId;

        JSONObject record = HttpUtil.getData(url
                , new HashMap<String, String>() {{
                    put("Authorization", "Zoho-oauthtoken " + accessToken);
                }});

        if (Objects.nonNull(record)) {
            JSONArray users = record.getJSONArray("users");
            if (Objects.nonNull(users)) {
                return new ArrayList<>(users.toJavaList(JSONObject.class));
            }
        }
        return new ArrayList<>();
    }

    /**
     * 通过文件流的方式上传文件
     *
     * @param accessToken token
     * @param filePath    要上传的文件地址
     * @param serverUrl   请求地址
     * @return 返回结果
     */
    public static JSONObject uploadAttachmentByFileStream(String accessToken, String filePath, String serverUrl) {
        return HttpUtil.postFileByStream(accessToken, filePath, serverUrl);
    }

    /**
     * 获取附件列表 合同模板
     */
    public static List<JSONObject> getAttachmentList(String accessToken, String moduleId, String moduleName) {
        Set<JSONObject> set = new HashSet<>();

        String url = "https://www.zohoapis.com.cn/crm/v3/" + moduleName + "/" + moduleId + "/Attachments?fields=id,Owner,File_Name,Created_Time,Size";

        JSONObject record = HttpUtil.getData(url
                , new HashMap<String, String>() {{
                    put("Authorization", "Zoho-oauthtoken " + accessToken);
                }});
        if (Objects.nonNull(record)) {
            JSONArray data = record.getJSONArray("data");
            set.addAll(data.toJavaList(JSONObject.class));
        }
        return new ArrayList<>(set);
    }


    /**
     * 获取附件列表 合同模板
     */
    public static List<JSONObject> getAttachmentList(String accessToken, String moduleId) {
        Set<JSONObject> set = new HashSet<>();

        String url = "https://www.zohoapis.com.cn/crm/v3/Contract/" + moduleId + "/Attachments?fields=id,Owner,File_Name,Created_Time,Size";

        JSONObject record = HttpUtil.getData(url
                , new HashMap<String, String>() {{
                    put("Authorization", "Zoho-oauthtoken " + accessToken);
                }});
        if (Objects.nonNull(record)) {
            JSONArray data = record.getJSONArray("data");
            set.addAll(data.toJavaList(JSONObject.class));
        }
        return new ArrayList<>(set);
    }

    /**
     * 获取附件列表 开发上量奖励模块
     */
    public static List<JSONObject> getAttachmentListByIncentive(String accessToken, String moduleId) {
        Set<JSONObject> set = new HashSet<>();

        String url = "https://www.zohoapis.com.cn/crm/v3/Incentive_Agreement/" + moduleId + "/Attachments?fields=id,Owner,File_Name,Created_Time,Size";

        JSONObject record = HttpUtil.getData(url
                , new HashMap<String, String>() {{
                    put("Authorization", "Zoho-oauthtoken " + accessToken);
                }});
        if (Objects.nonNull(record)) {
            JSONArray data = record.getJSONArray("data");
            set.addAll(data.toJavaList(JSONObject.class));
        }
        return new ArrayList<>(set);
    }

    /**
     * 下载附件 合同模板
     */
    public static InputStream downloadAttachmentByName(String accessToken, String moduleId, String attachmentId, String moduleName) {

        String url = "https://www.zohoapis.com.cn/crm/v3/" + moduleName + "/" + moduleId + "/Attachments/" + attachmentId;

        InputStream record = HttpUtil.downloadAttachmentData(url
                , new HashMap<String, String>() {{
                    put("Authorization", "Zoho-oauthtoken " + accessToken);
                }});
        if (Objects.nonNull(record)) {
            return record;
        }
        return null;
    }

    /**
     * 下载附件 合同模板
     */
    public static InputStream downloadAttachment(String accessToken, String moduleId, String attachmentId) {

        String url = "https://www.zohoapis.com.cn/crm/v3/Contract/" + moduleId + "/Attachments/" + attachmentId;

        InputStream record = HttpUtil.downloadAttachmentData(url
                , new HashMap<String, String>() {{
                    put("Authorization", "Zoho-oauthtoken " + accessToken);
                }});
        if (Objects.nonNull(record)) {
            return record;
        }
        return null;
    }

    /**
     * 下载附件 开发上量奖励模板
     */
    public static InputStream downloadAttachmentByIncentice(String accessToken, String moduleId, String attachmentId) {

        String url = "https://www.zohoapis.com.cn/crm/v3/Incentive_Agreement/" + moduleId + "/Attachments/" + attachmentId;

        InputStream record = HttpUtil.downloadAttachmentData(url
                , new HashMap<String, String>() {{
                    put("Authorization", "Zoho-oauthtoken " + accessToken);
                }});
        if (Objects.nonNull(record)) {
            return record;
        }
        return null;
    }

    // 修改基础档案模板数据
    public static void updateBasicData(String id, JSONObject jsonObject) {
        Map<String, Object> paramsMap = new HashMap<>();
        JSONArray updateData = new JSONArray();
        String url = "https://www.zohoapis.com.cn/crm/v3/Accounts";
        jsonObject.put("id", id);
        updateData.add(jsonObject);
        paramsMap.put("data", updateData);
        log.info("基础档案模板数据更新 = " + new JSONObject(paramsMap));
        HttpUtil.putData(url, paramsMap);
    }

    // 修改目标医院数据
    public static void updateTargetData(String contractId, JSONObject jsonObject) {
        Map<String, Object> paramsMap = new HashMap<>();
        JSONArray updateData = new JSONArray();
        String url = "https://www.zohoapis.com.cn/crm/v3/TargetHospital";
        jsonObject.put("id", contractId);
        updateData.add(jsonObject);
        paramsMap.put("data", updateData);
        log.info("目标模板数据更新 = " + new JSONObject(paramsMap));
        HttpUtil.putData(url, paramsMap);
    }

    // 修改合同模板数据
    public static void updateContractData(String contractId, JSONObject jsonObject) {
        Map<String, Object> paramsMap = new HashMap<>();
        JSONArray updateData = new JSONArray();
        String url = "https://www.zohoapis.com.cn/crm/v3/Contract";
        jsonObject.put("id", contractId);
        updateData.add(jsonObject);
        paramsMap.put("data", updateData);
        log.info("合同模板数据更新 = " + new JSONObject(paramsMap));
        HttpUtil.putData(url, paramsMap);
    }

    // 修改合同模板数据,然后触发工作流
    public static void updateContractDataWorkflow(String contractId, JSONObject jsonObject) {
        Map<String, Object> paramsMap = new HashMap<>();
        JSONArray updateData = new JSONArray();
        String url = "https://www.zohoapis.com.cn/crm/v3/Contract";
        jsonObject.put("id", contractId);
        updateData.add(jsonObject);
        paramsMap.put("data", updateData);

        // 触发工作流，发送电子邮件给客服助理
        JSONArray workflow = new JSONArray();
        workflow.add("workflow");
        paramsMap.put("trigger", workflow);

        log.info("合同模板数据更新 = " + new JSONObject(paramsMap));
        HttpUtil.putData(url, paramsMap);
    }

    // 修改上量奖励模板数据
    public static void updateIncentiveData(String incentiveId, JSONObject jsonObject) {
        Map<String, Object> paramsMap = new HashMap<>();
        JSONArray updateData = new JSONArray();
        String url = "https://www.zohoapis.com.cn/crm/v3/Incentive_Agreement";
        jsonObject.put("id", incentiveId);
        updateData.add(jsonObject);
        paramsMap.put("data", updateData);
        log.info("合同模板数据更新 = " + new JSONObject(paramsMap));
        HttpUtil.putData(url, paramsMap);
    }

    // 修改用户信息模板数据
    public static void updateUserInfoData(String contractId, String newAccountId) {
        Map<String, Object> paramsMap = new HashMap<>();
        JSONArray updateData = new JSONArray();
        String url = "https://www.zohoapis.com.cn/crm/v3/User_Profile";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("id", contractId);
        jsonObject.put("Sign_Account_ID", newAccountId);
        updateData.add(jsonObject);
        paramsMap.put("data", updateData);
        log.info("用户信息模板数据更新 = " + new JSONObject(paramsMap));
        HttpUtil.putData(url, paramsMap);
    }

    // 修改基础档案模板数据
    public static void updateBaseData(String contractId, String newAccountId) {
        Map<String, Object> paramsMap = new HashMap<>();
        JSONArray updateData = new JSONArray();
        String url = "https://www.zohoapis.com.cn/crm/v3/Accounts";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("id", contractId);
        jsonObject.put("accountId_c", newAccountId);
        updateData.add(jsonObject);
        paramsMap.put("data", updateData);
        log.info("基础档案模板数据更新 = " + new JSONObject(paramsMap));
        HttpUtil.putData(url, paramsMap);
    }

    /**
     * COQLQuery
     */
    public List<JSONObject> COQLQuery(String accessToken, String selectQuery) {
        String url = "https://www.zohoapis.com.cn/crm/v4/coql";
        Map<String, Object> map = new HashMap<>();
        map.put("select_query", selectQuery);
        try {
            JSONObject jsonObject = HttpUtil.postDataByCOQLQuery(accessToken, url, map);
            if (Objects.nonNull(jsonObject)) {
                JSONArray data = jsonObject.getJSONArray("data");

                return data.toJavaList(JSONObject.class);
            }
        } catch (Exception e) {
            System.out.println("出现异常，selectQuery = " + selectQuery);
            return new ArrayList<>();
        }
        return new ArrayList<>();
    }

    // 修改目标医院销售指标
    public static void updateSaleTargetData(String token, String id) {

        JSONObject updateJson = new JSONObject();

        updateJson.put("Signed", true); // 已签署时间
        updateJson.put("field4", DateUtil.getToday()); // 已签署时间
        updateJson.put("id", id);

        String url = "https://www.zohoapis.com.cn/crm/v3/TargetHospitalIndicatorList";
        Map<String, Object> paramsMap = new HashMap<>();
        JSONArray updateData = new JSONArray();
        updateData.add(updateJson);
        paramsMap.put("data", updateData);
        log.info("parameter = " + new JSONObject(paramsMap));
        JSONObject result = HttpUtil.putDataByHead(token, url, paramsMap);
        System.out.println("result.toJSONString() = " + result.toJSONString());
    }

    // 批量修改目标医院销售指标
    public static void batchUpdateSaleTargetData(String token, JSONArray updateData) {
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("data", updateData);
        log.info("数据更新：" + new JSONObject(paramsMap));
        String url = "https://www.zohoapis.com.cn/crm/v3/TargetHospitalIndicatorList";
        HttpUtil.putDataByHead(token, url, paramsMap);
    }
}
